package com.utbm.lo54.dao.neo4j;

import java.util.Set;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;

import com.utbm.lo54.dao.CourseDAOInterface;
import com.utbm.lo54.dao.neo4j.Neo4jUtility.RelTypes;
import com.utbm.lo54.entity.Course;

public class Neo4jCourseDAO implements CourseDAOInterface{

	@Override
	public Course create(Course co) {
		Node firstNode;

		GraphDatabaseService graphDb = Neo4jUtility.getGraphDatabase();

		Transaction tx = graphDb.beginTx();
		try
		{
			Node foundNode=Neo4jUtility.getNodeIndex().get("CODE", co.getCode()).getSingle();
			if (foundNode!=null) return nodeToCourse(foundNode);
			firstNode = Neo4jUtility.createAndIndex("CODE", co.getCode());
			courseToNode(co,firstNode);
			co.setId(firstNode.getId());
			firstNode.createRelationshipTo(Neo4jUtility.getRootNode(), Neo4jUtility.RelTypes.PROPOSED);
			tx.success();
		}
		finally
		{
			tx.finish();
		}
		return co;
	}

	@Override
	public void delete(Course co) {
		Node courseNode;
		GraphDatabaseService graphDb = Neo4jUtility.getGraphDatabase();
		Transaction tx = graphDb.beginTx();
		try
		{
			
			courseNode = graphDb.getNodeById(co.getId());
			Neo4jUtility.getNodeIndex().remove(courseNode);
			Iterable<Relationship> rels = courseNode.getRelationships(); // Get all the relationships and iterate to delete them one by one
			for(Relationship rel : rels){
				rel.delete();
			}
			courseNode.delete();			
			tx.success();
		}
		finally
		{
			tx.finish();
		}

	}

	@Override
	public Course findByCode(String code) {
		Node foundNode=Neo4jUtility.getNodeIndex().get("CODE", code).getSingle();
		if (foundNode!=null) return nodeToCourse(foundNode);
		return null;
	}

	public static Course nodeToCourse(Node n){
		Course c = new Course();
		c.setCode((n.getProperty(CourseProperties.CODE.name()).toString()));
		c.setTitle((String) n.getProperty(CourseProperties.TITLE.name()));
		c.setId(n.getId());
		return c;

	}

	public static Node courseToNode(Course c, Node n){
		n.setProperty(CourseProperties.TITLE.name(), c.getTitle());
		n.setProperty(CourseProperties.CODE.name(), c.getCode());
		n.setProperty(CourseProperties.TYPE.name(), "COURSE");
		return n;
	}

	@Override
	public Course findByTitle(String title) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void update(Course co) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public Set<Course> getAllCourse() {
		// TODO Auto-generated method stub
		return null;
	}

}
